package cn.demoncat.util.io.entity;

import net.coobird.thumbnailator.filters.Watermark;
import net.coobird.thumbnailator.geometry.AbsoluteSize;
import net.coobird.thumbnailator.geometry.Coordinate;
import net.coobird.thumbnailator.geometry.Position;
import net.coobird.thumbnailator.geometry.Region;
import org.apache.commons.lang3.StringUtils;

import java.awt.image.BufferedImage;
import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 图片处理参数
 * 
 * @author 延晓磊
 *
 * @since 2019年10月23日
 */
public class ImgParam {

	// 操作后是否关闭流
	private boolean close = true;
	// 旋转角度：-360 ~ 360
	private Double rotate;
	// 缩放标识：100 表示width=100(对称拉伸)；100o100表示width=100|height=100(智能拉伸)；100x100表示width=100&height=100(强制拉伸)
	private String zoom;
	// 宽：如果为null则按高度等比例（优化级低于zoom）
	private Integer width;
	// 高：如果为null则按宽度等比例，如果宽高都不为空则强制拉伸（优化级低于zoom）
	private Integer height;
	// 缩放比例：等比例缩放（优先级低于width,height）
	private Double scale = 1.0;
	// 裁切：指定裁剪区域 x,y,width,height
	private Region crop;
	// 压缩：0 ~ 1
	private Double quality;
	// 水印：位置，图片，透明度(0 ~ 1)
	private Watermark watermark;
	// 转换格式：png,jpg,gif
	private String format;
	// 将超过alpha的像素设置为透明
	private int alpha;

	/**
	 * 创建图片参数
	 */
	private ImgParam() {
		super();
	}
	
	/**
	 * 创建图片处理参数
	 * 
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月23日
	 */
	public static ImgParam build() {
		return new ImgParam();
	}
	
	public boolean isClose() {
		return close;
	}

	/**
	 * 设置操作完成后是否关闭流，默认true
	 * 
	 * @param close
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月23日
	 */
	public ImgParam close(boolean close) {
		this.close = close;
		return this;
	}

	public Double getRotate() {
		return rotate;
	}

	/**
	 * 设置旋转角度：-360 ~ 360
	 * 
	 * @param rotate
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月23日
	 */
	public ImgParam rotate(Double rotate) {
		this.rotate = rotate;
		return this;
	}

	public String getZoom() {
		return zoom;
	}

	/**
	 * 设置缩放规则：100 表示width=100(对称拉伸)；100o100表示width=100|height=100(智能拉伸)；100x100表示width=100&height=100(强制拉伸)
	 * 
	 * @param zoom
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月23日
	 */
	public ImgParam zoom(String zoom) {
		this.zoom = zoom;
		return this;
	}

	public Integer getWidth() {
		return width;
	}

	/**
	 * 设置缩放宽：如果为null则按高度等比例，如果宽高都不为空则强制拉伸（优化级低于zoom）
	 * 
	 * @param width
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月23日
	 */
	public ImgParam width(Integer width) {
		this.width = width;
		return this;
	}

	public Integer getHeight() {
		return height;
	}

	/**
	 * 高：如果为null则按宽度等比例，如果宽高都不为空则强制拉伸（优化级低于zoom）
	 * 
	 * @param height
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月23日
	 */
	public ImgParam height(Integer height) {
		this.height = height;
		return this;
	}

	public Double getScale() {
		return scale;
	}
	/**
	 * 缩放比例：等比例缩放（优先级低于width,height）
	 * 
	 * @param scale
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月23日
	 */
	public ImgParam scale(Double scale) {
		this.scale = scale;
		return this;
	}
	
	public Region getCrop() {
		return crop;
	}

	/**
	 * 设置裁切
	 * 
	 * @param crop	裁剪区域
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月23日
	 */
	public ImgParam crop(Region crop) {
		this.crop = crop;
		return this;
	}
	
	/**
	 * 设置裁切
	 * 
	 * @param position	原点位置
	 * @param width		宽
	 * @param height	高
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月23日
	 */
	public ImgParam crop(Position position, int width, int height) {
		return crop(new Region(position, new AbsoluteSize(width, height)));
	}

	/**
	 * 设置裁切
	 * 
	 * @param x			原点X
	 * @param y			原点y
	 * @param width		宽
	 * @param height	高
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月23日
	 */
	public ImgParam crop(int x, int y, int width, int height) {
		return crop(new Region(new Coordinate(x, y), new AbsoluteSize(width, height)));
	}
	
	public Double getQuality() {
		return quality;
	}

	/**
	 * 设置质量压缩：0 ~ 1
	 * 
	 * @param quality
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月23日
	 */
	public ImgParam quality(Double quality) {
		this.quality = quality;
		return this;
	}

	/**
	 * 自适应压缩比例
	 * 
	 * @param size	数据长度
	 * @param limit	限制长度
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月23日
	 */
	public ImgParam quality(long size, long limit) {
		if (size > limit) {
			this.quality = BigDecimal.valueOf(limit).divide(BigDecimal.valueOf(size), 4, RoundingMode.CEILING).doubleValue();
		}
		return this;
	}
	
	public Watermark getWatermark() {
		return watermark;
	}

	/**
	 * 设置水印：位置，图片，透明度(0 ~ 1)
	 * 
	 * @param watermark
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月23日
	 */
	public ImgParam watermark(Watermark watermark) {
		this.watermark = watermark;
		return this;
	}

	/**
	 * 设置水印
	 * 
	 * @param position		位置(Positions)
	 * @param img			水印图
	 * @param opacity		透明度(0 ~ 1)
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月23日
	 */
	public ImgParam watermark(Position position, BufferedImage img, float opacity) {
		this.watermark = new Watermark(position, img, opacity);
		return this;
	}
	
	/**
	 * 设置水印
	 * 
	 * @param x				原点X
	 * @param y				原点y
	 * @param img			水印图
	 * @param opacity		透明度(0 ~ 1)
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年10月23日
	 */
	public ImgParam watermark(int x, int y, BufferedImage img, float opacity) {
		this.watermark = new Watermark(new Coordinate(x, y), img, opacity);
		return this;
	}
	
	
	public String getFormat() {
		return format;
	}

	/**
	 * 转换格式：png,jpg,gif
	 * 
	 * @param format
	 * 
	 * @author 延晓磊
	 * @return 
	 *
	 * @since 2019年10月23日
	 */
	public ImgParam format(String format) {
		this.format = format;
		return this;
	}

	/**
	 * 设置透明度标记
	 *
	 * @param alpha		透明阀值：0表示不设置，255表示将白色设置为透明（转PNG图片）
	 * @return
	 *
	 * @author 延晓磊
	 * @since 2024年01月22日
	 */
	public ImgParam alpha(Integer alpha){
		this.alpha = alpha == null ? 0 : alpha;
		return this;
	}

	/**
	 * 获取透明度标记
	 *
	 * @return 透明阀值：0表示不设置，255表示将白色设置为透明（转PNG图片）
	 *
	 * @author 延晓磊
	 * @since 2024年01月22日
	 */
	public int getAlpha(){
		return this.alpha;
	}

	/**
	 * 是否为透明度标记
	 *
	 * @param alpha
	 * @return
	 */
	public static boolean isAlpha(Integer alpha){
		return alpha != null && alpha > 0;
	}

	/**
	 * 是否需要处理
	 *
	 * @param zoom
	 * @param water
	 * @param alpha
	 * @return
	 */
	public static boolean isNeed(String zoom, String water, Integer alpha){
		return StringUtils.isNotBlank(zoom) || StringUtils.isNotBlank(water) || isAlpha(alpha);
	}
}
